/**
 * 394. 字符串解码
 * https://leetcode-cn.com/problems/decode-string/
 */

const leftCode = '['.charCodeAt(0);
const rightCode = ']'.charCodeAt(0);
const zeroCode = '0'.charCodeAt(0);
const nineCode = '9'.charCodeAt(0);

/**
 * @param {string} s
 * @return {string}
 */
function decodeString(s) {
  const aheadStack = new Array(15);
  const countStack = new Array(15).fill(1);
  let top = -1;
  let accumulation = '';
  let num = 1;
  for (let i = 0; i < s.length; i += 1) {
    const code = s.codePointAt(i);
    if (code === leftCode) {
      top += 1;
      aheadStack[top] = accumulation;
      countStack[top] = num;
      accumulation = '';
      num = 1;
    } else if (code === rightCode) {
      const ahead = aheadStack[top];
      const count = countStack[top];
      top -= 1;
      let str = '';
      for (let j = 0; j < count; j += 1) {
        str += accumulation;
      }
      str = ahead + str;
      accumulation = str;
    } else if (code >= zeroCode && code <= nineCode) {
      let j = i + 1;
      while (j < s.length) {
        const nextCode = s.charCodeAt(j);
        if (!(nextCode >= zeroCode && nextCode <= nineCode)) {
          break;
        }
        j += 1;
      }
      num = parseInt(s.substring(i, j), 10);
      i = j - 1;
    } else {
      let j = i + 1;
      while (j < s.length) {
        const nextCode = s.charCodeAt(j);
        if (
          (nextCode >= zeroCode && nextCode <= nineCode)
          || nextCode === leftCode || nextCode === rightCode
        ) {
          break;
        }
        j += 1;
      }
      accumulation += s.substring(i, j);
      i = j - 1;
    }
  }
  return accumulation;
}

console.log(decodeString('3[a]2[bc]') === 'aaabcbc');
console.log(decodeString('3[a2[c]]') === 'accaccacc');
console.log(decodeString('2[abc]3[cd]ef') === 'abcabccdcdcdef');
console.log(decodeString('abc3[cd]xyz') === 'abccdcdcdxyz');
console.log(decodeString('abc') === 'abc');
